//copyright (c) 2016 L.W.C<lwc@li.cm>

#include "NCdo.h"

int TypeTyp(value *v1,value *v2){
	int typ=1;
	if(v1->type==VLTP_DOUBLE){
		typ=2;
	}
	typ*=10;
	if(v2->type==VLTP_DOUBLE){
		typ+=2;
	}
	else
	{
		typ+=1;
	}
	
	return typ;
	
}

void n_add(NC *nc){
	value v1,v2;
	int typ;
	int t;
	
	nc->val=pop(nc->val,&v1);
	nc->val=pop(nc->val,&v2);
	
	typ=TypeTyp(&v1,&v2);
	
	switch(typ){
		case 11:
			v2.u.i+=v1.u.i;
		break;
		case 12:
			v2.u.d+=(double)v1.u.i;
		case 21:
			v2.type=VLTP_DOUBLE;
			t=v2.u.i;
			v2.u.d=(double)t;
			v2.u.d+=v1.u.d;
		break;
		case 22:
			v2.u.d+=v1.u.d;
		break;
	}
	nc->val=push(nc->val,v2);
}

void n_sub(NC *nc){
	value v1,v2;
	int typ;
	int t;
	
	nc->val=pop(nc->val,&v1);
	nc->val=pop(nc->val,&v2);
	
	typ=TypeTyp(&v1,&v2);
	
	switch(typ){
		case 11:
			v2.u.i-=v1.u.i;
		break;
		case 12:
			v2.u.d-=(double)v1.u.i;
		case 21:
			v2.type=VLTP_DOUBLE;
			t=v2.u.i;
			v2.u.d=(double)t;
			v2.u.d-=v1.u.d;
		break;
		case 22:
			v2.u.d-=v1.u.d;
		break;
	}
	nc->val=push(nc->val,v2);
}

void n_mul(NC *nc){
	value v1,v2;
	int typ;
	int t;
	
	nc->val=pop(nc->val,&v1);
	nc->val=pop(nc->val,&v2);
	
	typ=TypeTyp(&v1,&v2);
	
	switch(typ){
		case 11:
			v2.u.i*=v1.u.i;
		break;
		case 12:
			v2.u.d*=(double)v1.u.i;
		case 21:
			v2.type=VLTP_DOUBLE;
			t=v2.u.i;
			v2.u.d=(double)t;
			v2.u.d*=v1.u.d;
		break;
		case 22:
			v2.u.d*=v1.u.d;
		break;
	}
	nc->val=push(nc->val,v2);
}

void n_div(NC *nc){
	value v1,v2;
	int typ;
	int t;
	
	nc->val=pop(nc->val,&v1);
	nc->val=pop(nc->val,&v2);
	
	typ=TypeTyp(&v1,&v2);
	
	switch(typ){
		case 11:
			v2.u.i/=v1.u.i;
		break;
		case 12:
			v2.u.d/=(double)v1.u.i;
		case 21:
			v2.type=VLTP_DOUBLE;
			t=v2.u.i;
			v2.u.d=(double)t;
			v2.u.d/=v1.u.d;
		break;
		case 22:
			v2.u.d/=v1.u.d;
		break;
	}
	nc->val=push(nc->val,v2);
}

void _do(NC *nc)
{
	value s1;
	value v1,v2;
/*	nc->val=pop(nc->val,&v1);
	nc->val=pop(nc->val,&v2);*/
	nc->sym=pop(nc->sym,&s1);
	nc->symnum--;
	//printf("%d%c%d\n",v2.u.i,s1.u.sym[0],v1.u.i);
	
	switch(s1.u.sym[0]){
		case '+':
			n_add(nc);
		break;
		case '-':
			n_sub(nc);
		break;
		case '*':
			n_mul(nc);
		break;
		case '/':
			n_div(nc);
		break;
		
		case ',':
			nc->val=pop(nc->val,&v1);
		/*	nc->val=pop(nc->val,&v2);
			nc->val=push(nc->val,v1);*/
			nc->stack=push(nc->stack,v1);
			//printf("-push:%d\n",v1.u.i);
		break;
		
		case '$':
			nc->val=pop(nc->val,&v1);
			nc->stack=push(nc->stack,v1);
			//printf("-push:%d\n",v1.u.i);
		case '#':
			nc->val=pop(nc->val,&v1);
			Call_Fun(nc,v1.u.name);
			//printf("-fun:%s\n",v1.u.name);
			/*v1.type=VLTP_INT;
			v1.u.i=1;
			nc->val=push(nc->val,v1);*/
		break;
	}
	
}